package com.niiwoo.civet.trade.service.local.contract;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.trade.dao.entity.AdvanceConfig;
import com.niiwoo.civet.trade.dao.mapper.AdvanceConfigMapperExt;
import com.niiwoo.civet.trade.enums.BorrowerTypeEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.civet.trade.constant.DatePatternConstant;
import com.niiwoo.civet.trade.dao.entity.FadadaContractTemplateFile;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectContract;
import com.niiwoo.civet.user.dto.UserPersonalDubboInfoDTO;
import com.niiwoo.civet.user.dto.request.SimpleOrgInfo;
import com.niiwoo.civet.user.dto.response.UserIdentityInfoResponseDTO;
import com.niiwoo.civet.user.enums.OrganizationEnum;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.civet.user.service.UserDataDubboService;
import com.niiwoo.civet.user.service.UserIdentityDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO.DynamicTable;
import com.niiwoo.tripod.fadada.dto.response.FadadaResponseDTO;
import com.niiwoo.tripod.fadada.enums.SignClientRoleEnum;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;

/**
 * 预仲裁合同
 * 
 * @author liaojunjun
 *
 */
@Service
public class ArbitrationContract extends AbstractFadadaContract {
	
	private static final Logger logger = LoggerFactory.getLogger(ArbitrationContract.class);

	@Autowired
	private SnowflakeIdWorker snowflakeIdWorker;

	@Reference(version = "1.0.0")
	private UserIdentityDubboService userIdentityDubboService;

	@Reference(version = "1.0.0")
	private UserDataDubboService userDataDubboService;

	@Reference(version = "1.0.0")
	private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;
	
	@Reference(version = "1.0.0")
	private OrganizationDubboService organizationDubboService;
	
	@Autowired
    private StringRedisTemplate stringRedisTemplate;
	
	@Autowired
	private PrivacyMasks privacyMasks;

	@Autowired
	AdvanceConfigMapperExt advanceConfigMapperExt;

	@Override
	public ProjectContract contractHandler(FadadaContractTemplateFile contractTemplate, String bizContractNo,
										   Project project, String userId) throws Exception{
		logger.info("预仲裁合同处理开始... projectId:{}", project.getProjectId());
		String contractId = snowflakeIdWorker.nextId() + "";
		UserIdentityInfoResponseDTO borrower = userIdentityDubboService.get(project.getBorrowUserId());
		SimpleOrgInfo borrowOrg = organizationDubboService.getByOrgId(project.getBorrowUserId());
		

		SimpleOrgInfo guarantee = organizationDubboService.getByOrgId(project.getGuaranteeCompanyOrgId());
		if(guarantee == null){
			logger.error("预仲裁合同处理异常 guarantee is null. projectId:{},orgId:{}, project.getGuaranteeCompanyOrgId:{}", project.getProjectId(), project.getOrgId(), JSON.toJSON(project.getGuaranteeCompanyOrgId()));
			throw new BizException("TRD10005", "预仲裁合同处理异常 guarantee is null");
		}

		this.generateContract(contractTemplate, contractId, bizContractNo, project, borrower, borrowOrg, guarantee);

		ProjectContract result = this.signContract(contractTemplate, contractId, project, borrower, borrowOrg, guarantee);

		this.contractFilling(contractId);
		logger.info("预仲裁合同处理结束... projectId:{}", project.getProjectId());
		return result;
	}
	
	/**
	 * 仲裁调解协议的案号规则调整为：所有拿下业务均使用同一个大编号“（2018）北国仲字第1539号案”
	 *	以12个英文字母（大写）ABCDEFGHIJKL分别代表12个月，
	 *  具体业务对应的案号规则为：（2018）北国仲字第1539-对应月份对应的英文字母+年份最后一位数+七位的序号”。
	 *  如2017年12月份的第1单拿下业务，则该业务仲裁调解协议对应的案号为：（2017）北国仲字第1539-L70000001,
	 *  2017年12月份的第10单拿下业务则该业务仲裁调解协议对应的案号为：（2017）北国仲字第1539-L70000010；
	 *  2018年一月的第1单拿下业务，则该业务仲裁调解协议对应的案号为：（2018）北国仲字第1539-A80000001，依次类推。
	 * @return
	 * @throws ParseException 
	 */
	private String getCaseStr() {
		String monthCodes = "ABCDEFGHIJKL";
		Date date = new Date();
		String monthCode = monthCodes.charAt(date.getMonth()) + "";
		String yearLast = DateFormatUtils.format(date, "yyyy").substring(3);
		
		// redis记录一个每月放款数量提供给仲裁补充协议中案号使用
		Long monthLendCount = stringRedisTemplate.boundValueOps("PROJECT_LEND_MONTH_"+FastDateFormat.getInstance(DatePatternConstant.YYYYMM).format(new Date())).increment(1);

		return monthCode + yearLast + StringUtils.leftPad(String.valueOf(monthLendCount), 7, '0');
	}
	
	private void generateContract(FadadaContractTemplateFile contractTemplate, String contractId, String bizContractNo,
			Project project, UserIdentityInfoResponseDTO borrower, SimpleOrgInfo borrowOrg, SimpleOrgInfo guarantee) throws Exception{
		logger.info("预仲裁合同生成开始... projectId:{}", project.getProjectId());
		UserPersonalDubboInfoDTO userPersonalDubboInfoDTO = userDataDubboService.userPersonalInfo(project
				.getBorrowUserId());

		GenerateContractRequestDTO dto = new GenerateContractRequestDTO();

		dto.setContractId(contractId);
		dto.setDocTitle(contractTemplate.getTemplateName());
		dto.setTemplateId(contractTemplate.getTemplateId());

		Map<String, String> parameterMap = new HashMap<String, String>();

		//parameterMap.put("applyDate", DateFormatUtils.format(project.getPublishTime(), "yyyy年MM月dd日"));
//		parameterMap.put("contractNo", bizContractNo);
		parameterMap.put("year", DateFormatUtils.format(new Date(), "yyyy"));
		parameterMap.put("case", getCaseStr());
//		parameterMap.put(
//				"borrowAmount",
//				project.getContractAmount()
//						.setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString()); // 借款金额
//		parameterMap.put("deadLine", project.getDeadline() + "");// 借款期限
//		parameterMap.put("investRate", project.getBorrowRate().multiply(new BigDecimal(AmountHandleConstant.HUNDRED))
//				.setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString());// 借款年利率
//		parameterMap.put("repaymentTypeName", RepaymentTypeEnum.enumOf(project.getRepaymentType()).getDesc());

		parameterMap.put("guarantee", guarantee.getOrganizationName());
		//parameterMap.put("guaranteeLinkman", guarantee.getRepresentative());
		parameterMap.put("guaranteePhoneNo", StringUtils.isNoneBlank(guarantee.getLegalPersonPhoneNumber()) ? privacyMasks.decryptPrivacy(guarantee.getLegalPersonPhoneNumber()) : "");
		parameterMap.put("guaranteeAddress", guarantee.getAddress());
		parameterMap.put("guaranteeEmail", guarantee.getEmail());

		if(BorrowerTypeEnum.PERSONAL.getType().equals(project.getBorrowerType())) {
			parameterMap.put("borrowerName", borrower.getName());
			parameterMap.put("borrowerPhoneNo", privacyMasks.decryptPrivacy(project.getBorrowMobile()));
			parameterMap.put("borrowerAddress", borrower.getAddress());
			parameterMap.put("borrowerEmail", StringUtils.isNoneBlank(project.getBorrowEmail()) ? project.getBorrowEmail() : userPersonalDubboInfoDTO.getEmail());
		} else {
			parameterMap.put("borrowerName", borrowOrg.getOrganizationName());
			parameterMap.put("borrowerPhoneNo", StringUtils.isNoneBlank(borrowOrg.getLegalPersonPhoneNumber()) ? privacyMasks.decryptPrivacy(borrowOrg.getLegalPersonPhoneNumber()) : "");
			parameterMap.put("borrowerAddress", borrowOrg.getAddress());
			parameterMap.put("borrowerEmail", StringUtils.isNoneBlank(project.getBorrowEmail()) ? project.getBorrowEmail() : borrowOrg.getEmail());
		}

		//parameterMap.put("antiGuarantee", antiGuarantee.getOrganizationName());
		//parameterMap.put("antiGuaranteeLinkman", antiGuarantee.getRepresentative());
//		parameterMap.put("antiGuaranteePhoneNo", antiGuarantee.getLegalPersonPhoneNumber());
//		parameterMap.put("antiGuaranteeAddress", antiGuarantee.getAddress());
//		parameterMap.put("antiGuaranteeEmail", antiGuarantee.getEmail());
		
		//parameterMap.put("signDate", DateFormatUtils.format(new Date(), "yyyy年MM月dd日"));

		dto.setParameterMap(parameterMap);

		// 签章列表
		List<List<String>> signatureNamesList = new ArrayList<>();

		// 签章信息
		String guaranteeSignatureNamesText = "                申请人（签章）：" + guarantee.getOrganizationName();
		List<String> guaranteeSignatureNamesCells = new ArrayList<>();
		guaranteeSignatureNamesCells.add(guaranteeSignatureNamesText);
		signatureNamesList.add(guaranteeSignatureNamesCells);

		// 签章信息
		String borrowerSignatureNamesText;
		if(BorrowerTypeEnum.PERSONAL.getType().equals(project.getBorrowerType())) {
			borrowerSignatureNamesText = "                被申请人（签章）：" + borrower.getName();
		} else {
			borrowerSignatureNamesText = "                被申请人（签章）：" + borrowOrg.getOrganizationName();
		}
		List<String> borrowerSignatureNamesCells = new ArrayList<>();
		borrowerSignatureNamesCells.add(borrowerSignatureNamesText);
		signatureNamesList.add(borrowerSignatureNamesCells);

		// 签章信息
//		String antiGuaranteeSignatureNamesText = "                被申请人（签章）：" + antiGuarantee.getOrganizationName();
//		List<String> antiGuaranteeSignatureNamesCells = new ArrayList<>();
//		antiGuaranteeSignatureNamesCells.add(antiGuaranteeSignatureNamesText);
//		signatureNamesList.add(antiGuaranteeSignatureNamesCells);

		List<String> headers = new ArrayList<>();
		headers.add("");
		// 所有人签名 在pdf合同模板的keyword下面插入(正好在页尾，不用留空白)，需要留够空白，不然会覆盖下面的内容
		DynamicTable signNameTable = new DynamicTable();
		signNameTable.setInsertWay(1);
		signNameTable.setKeyword("以本协议内容为准。");
		signNameTable.setCellHeight(60f);
		signNameTable.setHeaders(headers);
		// 签名时需要增加高度并居中显示
		signNameTable.setCellVerticalAlignment(5);
		signNameTable.setDatas(signatureNamesList);
		signNameTable.setBorderFlag(false);
		List<DynamicTable> tables = new ArrayList<DynamicTable>();
		tables.add(signNameTable);

		dto.setDynamicTables(tables);

		generateContract(dto);
		logger.info("预仲裁合同生成结束... projectId:{}", project.getProjectId());
	}

	private ProjectContract signContract(FadadaContractTemplateFile contractTemplate, String contractId,
			Project project, UserIdentityInfoResponseDTO borrower, SimpleOrgInfo borrowOrg, SimpleOrgInfo guarantee) throws Exception{
		String METHOD_NAME = "法大大合同自动签署-仲裁调解协议 projectId:" + project.getProjectId();
		logger.info(METHOD_NAME);
		String docTitle;
		if(BorrowerTypeEnum.PERSONAL.getType().equals(project.getBorrowerType())) {
		 	docTitle = borrower.getName() + "的仲裁调解协议_" + contractId;
		} else {
			docTitle = borrowOrg.getOrganizationName() + "的仲裁调解协议_" + contractId;
		}

		// 担保公司签署
		String transactionId = snowflakeIdWorker.nextId() + "";
		String guaranteeCaCertId = guarantee.getFadadaCacertId();
		String guaranteeSignKeyword = "申请人（签章）：" + guarantee.getOrganizationName();
		FadadaResponseDTO fadadaResponse = extSignAuto(transactionId, contractId, guaranteeCaCertId,
				SignClientRoleEnum.GUARANTEE.getValue(), docTitle, guaranteeSignKeyword);
		logger.info("法大大合同自动签署-仲裁调解协议 担保公司签署结束... projectId:{}", project.getProjectId());
		// 借款人签署
		transactionId = snowflakeIdWorker.nextId() + "";
		if(BorrowerTypeEnum.PERSONAL.getType().equals(project.getBorrowerType())) {
			String borrowerCaCertId = userAuthorizationInfoDubboService.getUserAuthorizationInfo(borrower.getUserId())
					.getFadadaCacertId();
			String borrowerSignKeyword = "被申请人（签章）：" + borrower.getName();
			fadadaResponse = extSignAuto(transactionId, contractId, borrowerCaCertId,
					SignClientRoleEnum.BORROWER.getValue(), docTitle, borrowerSignKeyword);
		} else {
			String borrowerCaCertId = borrowOrg.getFadadaCacertId();
			String borrowerSignKeyword = "被申请人（签章）：" + borrowOrg.getOrganizationName();
			fadadaResponse = extSignAuto(transactionId, contractId, borrowerCaCertId,
					SignClientRoleEnum.BORROWER.getValue(), docTitle, borrowerSignKeyword);
		}
		logger.info("法大大合同自动签署-仲裁调解协议 担保公司签署结束... projectId:{}", project.getProjectId());
		// 反担保公司签署
//		transactionId = snowflakeIdWorker.nextId() + "";
//		String antiGuaranteeCaCertId = antiGuarantee.getFadadaCacertId();
//		String antiGuaranteeSignKeyword = "被申请人（签章）：" + antiGuarantee.getOrganizationName();
//		fadadaResponse = extSignAuto(transactionId, contractId, antiGuaranteeCaCertId,
//				SignClientRoleEnum.GUARANTEE.getValue(), docTitle, antiGuaranteeSignKeyword);
		logger.info("法大大合同自动签署-仲裁调解协议 反担保公司签署结束... projectId:{}", project.getProjectId());
		return this.buildContractUpdateRecord(contractTemplate.getTemplateId(), contractId, transactionId,
				fadadaResponse.getViewUrl(), fadadaResponse.getDownloadUrl());
	}

}
